﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using KBEngine.Common;

namespace KBEngineTool.Forms.Entity
{
    public partial class LoggerWidget : UserControl
    {
        LoggerWatcher watcher;
        LogType _logType;
        HashSet<ComponentType> _comTypes = new HashSet<ComponentType>();
        int _uid;
        int _globalOrder; //app启动顺序， global为全局(如dbmgr，cellapp的顺序)启动顺序
        int _groupOrder;  //group为组启动顺序(如:所有baseapp为一组)
        string _date = string.Empty; //这个作用与keyStr一致
        string _keyStr = string.Empty;

        public LoggerWidget()
        {
            InitializeComponent();
            this.Load += LoggerWidget_Load;
        }

        private void LoggerWidget_Load(object sender, EventArgs e)
        {
            KBEngine.Event.registerOut(KBEngine.MachineEvent.OnQueryAllInterfaces, this, nameof(__QueryAllInterfaces));

            //初始化过滤数据
            _uid = Define.getDefaultUID();
            foreach (LogType item in Enum.GetValues(typeof(LogType)))
            {
                _logType |= item;
            }
            for (var comType = ComponentType.unknown + 1; comType < ComponentType.end; ++comType)
            {
                _comTypes.Add(comType);
            }
            //以下app不会在Logger上记录日志 debug_helper.cpp  DebugHelper::onMessage
            _comTypes.Remove(ComponentType.machine);
            _comTypes.Remove(ComponentType.console);
            _comTypes.Remove(ComponentType.logger);
            _comTypes.Remove(ComponentType.client);

            Txt_GlobalOrder.Value = _globalOrder;
            Txt_GroupOrder.Value = _groupOrder;
            Txt_Date.Text = _date;
            Txt_KeyStr.Text = _keyStr;

            //根据数据改变对应CheckBox的状态
            var controlList = GetChildControl(Group_Process);
            foreach (var item in controlList)
            {
                if (item.Tag == null)
                    continue;
                CheckBox checkBox = item as CheckBox;
                var strComType = (string)item.Tag;
                var comType = (ComponentType)Enum.Parse(typeof(ComponentType), strComType);
                checkBox.Checked = _comTypes.Contains(comType);
            }

            controlList = GetChildControl(Group_Filter);
            foreach (var item in controlList)
            {
                if (item.Tag == null)
                    continue;
                CheckBox checkBox = item as CheckBox;
                var strLogType = (string)item.Tag;
                var logType = (LogType)Enum.Parse(typeof(LogType), strLogType);
                checkBox.Checked = (_logType & logType) != 0;
            }
        }
        private List<Control> GetChildControl(Control control)
        {
            var child = new List<Control>();
            foreach (var item in control.Controls)
            {
                var panel = item as Panel;
                if (panel != null)
                    child.AddRange(GetChildControl(panel));
                child.Add((Control)item);
            }
            return child;
        }

        public void LogMsg(List<string> msgList)
        {
            if (this.Txt_Context.TextLength > 10000)
            {
                var delLen = this.Txt_Context.TextLength - 10000;
                this.Txt_Context.Select(0, delLen);
                this.Txt_Context.SelectedText = string.Empty;
            }
            foreach (var msg in msgList)
            {
                this.Txt_Context.AppendText(msg);
            }
        }

        private void Process_CheckedChanged(object sender, EventArgs e)
        {
            if (watcher == null) return;
            var checkBox = (CheckBox)sender;
            var componentType = (ComponentType)Enum.Parse(typeof(ComponentType), (string)checkBox.Tag);
            if (checkBox.Checked)
                _comTypes.Add(componentType);
            else
                _comTypes.Remove(componentType);
            ApplySetting();
        }
        private void Filter_CheckedChanged(object sender, EventArgs e)
        {
            if (watcher == null) return;
            var checkBox = (CheckBox)sender;
            var logType = (LogType)Enum.Parse(typeof(LogType), (string)checkBox.Tag);
            if (checkBox.Checked)
                _logType |= logType;
            else
                _logType &= ~logType;
            ApplySetting();
        }
        private void Btn_Apply_Click(object sender, EventArgs e)
        {
            _globalOrder = (int)Txt_GlobalOrder.Value;
            _groupOrder = (int)Txt_GroupOrder.Value;
            _date = Txt_Date.Text;
            _keyStr = Txt_KeyStr.Text;
            ApplySetting();
        }
        public void __QueryAllInterfaces()
        {
            var clientApp = Operation.Inst.ClientApp;
            if (clientApp.MachineList.Count < 0)
                return;

            var comInfos = clientApp.GetAppInfos(clientApp.MachineList[0].machineID);
            var loggerCom = comInfos.Find(item => item.componentType == ComponentType.logger);
            if (loggerCom != null)
            {
                watcher = new LoggerWatcher();
                watcher.connect(loggerCom.intaddr, loggerCom.intport);
                ApplySetting(true);
                watcher.receiveLog(LogMsg, true);
            }
        }

        private void ApplySetting(bool isFirst = false)
        {
            watcher.RegisterToLogger(_uid, _logType, _comTypes, false, isFirst, _globalOrder, _groupOrder, _date, _keyStr);
        }
    }
}
